#include <head.h>
void sys_error(const char *e)
{
    perror(e);
    exit(1);
}
void fn(char *p);
void sig_handler(int no)
{
    waitpid(-1, NULL, 0);
}
void *tfn(void *arg);
int main(int argc, char **argv)
{
    struct sockaddr_in6 addr;
    int serversocket = socket(AF_INET6, SOCK_STREAM, 0);
    if (serversocket == -1)
    {
        sys_error("socket error");
    }
    
    memset(&addr, 0, sizeof(addr));
    addr.sin6_family = AF_INET6;
    addr.sin6_port = htons(9000);
    addr.sin6_addr =in6addr_any;
    int r;
    // int r=  inet_pton(AF_INET,"127.0.0.1",&(addr.sin6_addr.s_addr));
    // if(r ==0){
    //     sys_error("inet_pton");
    // }
    r = bind(serversocket, (struct sockaddr *)&addr, sizeof(addr));
    if (r == -1)
    {
        sys_error("bind");
    }
    listen(serversocket, 10);
    struct sockaddr_in6 client;
    socklen_t l = sizeof(client);
    int fd;
    char buf [1024];
    while (1)
    {
        CLEAR_ARRAY(buf);
        memset(&client, 0, sizeof(client));
        fd = accept(serversocket, (struct sockaddr *)&client, &l);
        if (fd == -1)
        {
            sys_error("accept error");
        }
        printf("New connection from IP:%s,port:%d\n", inet_ntop(AF_INET6, &(client.sin6_addr), buf, sizeof(buf)), ntohs(client.sin6_port));
        pthread_t tid;
        r = pthread_create(&tid, NULL, tfn, (void *)fd);
        pthread_detach(tid);
    }
    return 0;
}
void fn(char *p)
{
    if (!p)
    {
        return;
    }
    while (*p)
    {
        *p = toupper(*p);
        p++;
    }
}
void *tfn(void *arg)
{
    int fd = (int)arg;
    int r=0;
    char buf[100];
    while (1)
    {
        CLEAR_ARRAY(buf);
        r = read(fd, buf, sizeof(buf));
        if (r == 0)
        {
            printf("client disconnected\n");
            close(fd);
            break;
        }
        else if (r == -1){
            printf("read error");
            pthread_exit(NULL);
        }
        printf("%s\n", buf);
        fn(buf);
        write(fd, buf, r);
    }
    return NULL;
}
